import numpy as np
import pandas as pd
import librosa as lb
import IPython.display as ipd
import matplotlib.pyplot as plt
import math
from numpy import linalg as LA
import scipy.io
from scipy.spatial.distance import hamming
# To execute a cell line by line
from IPython.core.interactiveshell import InteractiveShell
InteractiveShell.ast_node_interactivity = "all"
# Loading trs audio file
trs, samplerate1 = lb.load('data/trs.wav', sr = None)
print("Sample rate :", samplerate1)
print("Data shape :", trs.shape)
ipd.Audio('data/trs.wav')
# Loading trn audio file
trn, samplerate2 = lb.load('data/trn.wav', sr = None)
print("Sample rate :", samplerate2)
print("Data shape :", trn.shape)
ipd.Audio('data/trn.wav')
Sample rate : 16000 Data shape : (506166,)
Sample rate : 16000 Data shape : (506166,)
# Applying STFT with 1024 point frames and 50% overlap on trs audio and plotting it
trs_stft = lb.stft(trs, n_fft = 1024, hop_length = 512, window='hann',center=True, win_length=1024)
print("Shape of STFT of trs data :",trs_stft.shape)
S = abs(trs_stft)
plt.figure(figsize=(6,6))
plt.imshow(S,aspect="auto")
plt.show()
Shape of STFT of trs data : (513, 989)
<Figure size 432x432 with 0 Axes>
<matplotlib.image.AxesImage at 0x1ef3f0b1640>
# Applying STFT with 1024 point frames and 50% overlap on trn audio and plotting it
trn_stft = lb.stft(trn, n_fft = 1024, hop_length = 512, window='hann',center=True, win_length=1024)
print("Shape of STFT of trn data :",trn_stft.shape)
N = abs(trn_stft)
plt.figure(figsize=(6,6))
plt.imshow(N,aspect="auto")
plt.show()
Shape of STFT of trn data : (513, 989)
<Figure size 432x432 with 0 Axes>
<matplotlib.image.AxesImage at 0x1ef3f398250>
# Mixture spectogram by adding trs and trn spectograms
G = S + N
print("Shape of G :", G.shape)
plt.figure(figsize=(6,6))
plt.imshow(abs(G),aspect="auto")
plt.show()
Shape of G : (513, 989)
<Figure size 432x432 with 0 Axes>
<matplotlib.image.AxesImage at 0x1ef3ffde820>
# Calculation of Ideal Binary Masks (IBM)
ibm_mix = np.ones((trs_stft.shape))
for i in range(trs_stft.shape[0]):
for j in range(trs_stft.shape[1]):
if abs(trs_stft[i, j]) >= abs(trn_stft[i, j]):
ibm_mix[i, j] = 1
else:
ibm_mix[i, j] = 0
print("Shape of the IBM mix matrix:", ibm_mix.shape)
Shape of the IBM mix matrix: (513, 989)
# Loading x_nmf audio file
x_nmf, samplerate3 = lb.load('data/x_nmf.wav', sr = None)
print("Sample rate :", samplerate3)
print("Data shape :", x_nmf.shape)
ipd.Audio('data/x_nmf.wav')
Sample rate : 16000 Data shape : (66560,)
# Applying STFT with 1024 point frames and 50% overlap on X and plotting it
X = lb.stft(x_nmf, n_fft = 1024, hop_length = 512, window = 'hann',center = True, win_length = 1024)
print("Shape of STFT of x_nmf data :", X.shape)
Y = abs(X)
plt.figure(figsize=(6,6))
plt.imshow(N,aspect="auto")
plt.show()
Shape of STFT of x_nmf data : (513, 131)
<Figure size 432x432 with 0 Axes>
<matplotlib.image.AxesImage at 0x1ef3fe69b80>
# Number of nearest neighbors
k = 11
# Finding the nearest neighbors and their median and plotting it
D_final = []
for i in range(Y.shape[1]):
D = []
for j in range(G.shape[1]):
D.append(LA.norm(Y[:,i] - G[:,j]))
D_sort = np.argsort(D)
k_ind = D_sort[0:k]
B = []
for a in k_ind:
B.append(ibm_mix[:,a])
B = np.array(B)
B = B.T
Dt = np.median(B, axis = 1)
D_final.append(Dt)
D_final = np.array(D_final)
D_final = D_final.T
plt.figure(figsize=(8,8))
plt.imshow(D_final, origin = 'lower')
plt.show()
<Figure size 576x576 with 0 Axes>
<matplotlib.image.AxesImage at 0x1ef3fed1eb0>
# Recovering the complex-valued spectrogram of speech by masking the input
S = np.multiply(X, D_final)
rec_S = lb.istft(S, n_fft = 1024, hop_length = 512, win_length = 1024, center=True)
print("Shape of recovered audio:", rec_S.shape)
# Audio of recovered signal
ipd.Audio(np.real(rec_S), rate = 16000)
Shape of recovered audio: (66560,)
From the above audio we observe that the noise is suppressed and the audio is denoised to " She had your dark suit greasy wash water all year".
# Loading the test and train datasets
eeg = scipy.io.loadmat('data/eeg.mat')
x_train = eeg['x_train']
print("Shape of x train data :", x_train.shape)
x_test = eeg['x_te']
print("Shape of x test data :", x_test.shape)
y_train = eeg['y_train']
print("Shape of y train data :", y_train.shape)
y_test = eeg['y_te']
print("Shape of y test data :", y_test.shape)
Shape of x train data : (768, 3, 112) Shape of x test data : (768, 3, 28) Shape of y train data : (112, 1) Shape of y test data : (28, 1)
# STFT for each patient and channel for x train
X_tr = np.empty((255,0))
for i in range(x_train.shape[2]):
PC_stft = []
for j in range(x_train.shape[1]):
PC_stft1 = lb.stft(x_train[:,j,i], n_fft = 64, hop_length = 48, window='blackman', center=True, win_length = 64)
PC_stft.append(PC_stft1[2:7])
PC_stft = np.array(PC_stft)
PC_stft = PC_stft.flatten().reshape(-1,1)
X_tr = np.append(X_tr, PC_stft, axis = 1)
print("Shape of STFT of x train data:", X_tr.shape)
Shape of STFT of x train data: (255, 112)
# STFT for each patient and channel for x test
X_te = np.empty((255,0))
for i in range(x_test.shape[2]):
PC_stft = []
for j in range(x_test.shape[1]):
PC_stft1 = lb.stft(x_test[:,j,i], n_fft = 64, hop_length = 48, window='blackman', center=True, win_length = 64)
PC_stft.append(PC_stft1[2:7])
PC_stft = np.array(PC_stft)
PC_stft = PC_stft.flatten().reshape(-1,1)
X_te = np.append(X_te, PC_stft, axis = 1)
print("Shape of STFT of x test data:", X_te.shape)
Shape of STFT of x test data: (255, 28)
# Coverting array of arrays to list of y test data
y_test1 = np.concatenate(y_test, axis = 0)
# Function to compute accuracy of knn
def accuracyCalc(y_true, y_pred):
pred_count = 0
for true, pred in zip(y_true, y_pred):
if true == pred:
pred_count += 1
accuracy = pred_count/len(y_true)
return accuracy
# Initialising a df to store maximum accuracy for each k value
acc_df = pd.DataFrame(columns = ['K', 'L', 'Accuracy'])
# KNN Classification
acc_list = []
for k in range(3, 19, 2):
for l in range(700, 730):
np.random.seed(0)
# Initialising random projection matrix
A = np.random.rand(l,255)
# Normalizing projection matrix
A = A/np.linalg.norm(A)
Y_tr = np.sign(np.dot(A, X_tr))
Y_te = np.sign(np.dot(A, X_te))
D_final = []
for i in range(Y_te.shape[1]):
D = []
for j in range(Y_tr.shape[1]):
# Calculating hamming distance points in test and train data
D.append(hamming(Y_te[:,i], Y_tr[:,j]))
# Getting the k neartest neighbors after sorting with smallest values
D_sort = np.argsort(D)
k_ind = D_sort[0:k]
B = []
for a in k_ind:
B.append(y_train[a,0])
B = np.array(B)
B = B.T
Dt = np.median(B)
D_final.append(Dt)
D_final = np.array(D_final)
D_final = D_final.T
acc = round(accuracyCalc(y_test1, D_final)*100,2)
acc_df.loc[len(acc_df.index)] = [k, l, acc]
print("Classification results with different choice of K and L : ")
acc_df.head(50)
Classification results with different choice of K and L :
| K | L | Accuracy | |
|---|---|---|---|
| 0 | 3.0 | 700.0 | 50.00 |
| 1 | 3.0 | 701.0 | 50.00 |
| 2 | 3.0 | 702.0 | 53.57 |
| 3 | 3.0 | 703.0 | 53.57 |
| 4 | 3.0 | 704.0 | 50.00 |
| 5 | 3.0 | 705.0 | 50.00 |
| 6 | 3.0 | 706.0 | 50.00 |
| 7 | 3.0 | 707.0 | 53.57 |
| 8 | 3.0 | 708.0 | 53.57 |
| 9 | 3.0 | 709.0 | 53.57 |
| 10 | 3.0 | 710.0 | 57.14 |
| 11 | 3.0 | 711.0 | 57.14 |
| 12 | 3.0 | 712.0 | 57.14 |
| 13 | 3.0 | 713.0 | 57.14 |
| 14 | 3.0 | 714.0 | 57.14 |
| 15 | 3.0 | 715.0 | 64.29 |
| 16 | 3.0 | 716.0 | 60.71 |
| 17 | 3.0 | 717.0 | 60.71 |
| 18 | 3.0 | 718.0 | 60.71 |
| 19 | 3.0 | 719.0 | 60.71 |
| 20 | 3.0 | 720.0 | 60.71 |
| 21 | 3.0 | 721.0 | 60.71 |
| 22 | 3.0 | 722.0 | 60.71 |
| 23 | 3.0 | 723.0 | 60.71 |
| 24 | 3.0 | 724.0 | 60.71 |
| 25 | 3.0 | 725.0 | 60.71 |
| 26 | 3.0 | 726.0 | 57.14 |
| 27 | 3.0 | 727.0 | 57.14 |
| 28 | 3.0 | 728.0 | 57.14 |
| 29 | 3.0 | 729.0 | 57.14 |
| 30 | 5.0 | 700.0 | 71.43 |
| 31 | 5.0 | 701.0 | 71.43 |
| 32 | 5.0 | 702.0 | 71.43 |
| 33 | 5.0 | 703.0 | 71.43 |
| 34 | 5.0 | 704.0 | 71.43 |
| 35 | 5.0 | 705.0 | 75.00 |
| 36 | 5.0 | 706.0 | 75.00 |
| 37 | 5.0 | 707.0 | 75.00 |
| 38 | 5.0 | 708.0 | 71.43 |
| 39 | 5.0 | 709.0 | 67.86 |
| 40 | 5.0 | 710.0 | 71.43 |
| 41 | 5.0 | 711.0 | 71.43 |
| 42 | 5.0 | 712.0 | 75.00 |
| 43 | 5.0 | 713.0 | 75.00 |
| 44 | 5.0 | 714.0 | 75.00 |
| 45 | 5.0 | 715.0 | 75.00 |
| 46 | 5.0 | 716.0 | 78.57 |
| 47 | 5.0 | 717.0 | 78.57 |
| 48 | 5.0 | 718.0 | 78.57 |
| 49 | 5.0 | 719.0 | 75.00 |
acc_df[acc_df['K'] == 5]
| K | L | Accuracy | |
|---|---|---|---|
| 30 | 5.0 | 700.0 | 71.43 |
| 31 | 5.0 | 701.0 | 71.43 |
| 32 | 5.0 | 702.0 | 71.43 |
| 33 | 5.0 | 703.0 | 71.43 |
| 34 | 5.0 | 704.0 | 71.43 |
| 35 | 5.0 | 705.0 | 75.00 |
| 36 | 5.0 | 706.0 | 75.00 |
| 37 | 5.0 | 707.0 | 75.00 |
| 38 | 5.0 | 708.0 | 71.43 |
| 39 | 5.0 | 709.0 | 67.86 |
| 40 | 5.0 | 710.0 | 71.43 |
| 41 | 5.0 | 711.0 | 71.43 |
| 42 | 5.0 | 712.0 | 75.00 |
| 43 | 5.0 | 713.0 | 75.00 |
| 44 | 5.0 | 714.0 | 75.00 |
| 45 | 5.0 | 715.0 | 75.00 |
| 46 | 5.0 | 716.0 | 78.57 |
| 47 | 5.0 | 717.0 | 78.57 |
| 48 | 5.0 | 718.0 | 78.57 |
| 49 | 5.0 | 719.0 | 75.00 |
| 50 | 5.0 | 720.0 | 71.43 |
| 51 | 5.0 | 721.0 | 75.00 |
| 52 | 5.0 | 722.0 | 75.00 |
| 53 | 5.0 | 723.0 | 75.00 |
| 54 | 5.0 | 724.0 | 64.29 |
| 55 | 5.0 | 725.0 | 67.86 |
| 56 | 5.0 | 726.0 | 67.86 |
| 57 | 5.0 | 727.0 | 67.86 |
| 58 | 5.0 | 728.0 | 71.43 |
| 59 | 5.0 | 729.0 | 67.86 |
# Calculating maximum accuracy for different values of K and plotting it
max_df = acc_df.groupby('K').agg({'Accuracy' : 'max'})
max_df.reset_index(inplace = True)
fig = plt.figure(figsize = (10, 5))
x = max_df['K']
y = max_df['Accuracy']
# creating the bar plot
plt.bar(x, y)
plt.xticks(np.arange(min(x), max(x)+1, 2))
# To print labels
for i in range(len(y)):
plt.annotate(str(y[i]), xy=(x[i],y[i]), ha='center', va='bottom')
plt.xlabel("K value")
plt.ylabel("Maximum accuracy (%)")
plt.title("Maximum accuracy for different values of K")
plt.show()
<BarContainer object of 8 artists>
([<matplotlib.axis.XTick at 0x1ef40ba0670>, <matplotlib.axis.XTick at 0x1ef40ba0640>, <matplotlib.axis.XTick at 0x1ef40b9c1c0>, <matplotlib.axis.XTick at 0x1ef40bdb4c0>, <matplotlib.axis.XTick at 0x1ef40bdb9d0>, <matplotlib.axis.XTick at 0x1ef40bdb6d0>, <matplotlib.axis.XTick at 0x1ef40be60d0>, <matplotlib.axis.XTick at 0x1ef40be65e0>], [Text(0, 0, ''), Text(0, 0, ''), Text(0, 0, ''), Text(0, 0, ''), Text(0, 0, ''), Text(0, 0, ''), Text(0, 0, ''), Text(0, 0, '')])
Text(3.0, 64.29, '64.29')
Text(5.0, 78.57, '78.57')
Text(7.0, 39.29, '39.29')
Text(9.0, 39.29, '39.29')
Text(11.0, 42.86, '42.86')
Text(13.0, 35.71, '35.71')
Text(15.0, 28.57, '28.57')
Text(17.0, 25.0, '25.0')
Text(0.5, 0, 'K value')
Text(0, 0.5, 'Maximum accuracy (%)')
Text(0.5, 1.0, 'Maximum accuracy for different values of K')
I evaluated Knn model for different values of k ranging from 3 to 17 and different values of L raning from 700 to 730. I was able to observe an optimal accuracy of 78.6% for the case of k = 5 and L ranging between 716 and 718.
Compared to the accuracy plot made using Naive Bayes classifier, we observe there is a drop in performance when classified using Knn. But the highest accuracy difference is not too high. The drop in accuracy maybe caused because of the following reasons:
# Loading data
mds = scipy.io.loadmat('data/MDS_pdist.mat')
M = mds['L']
print("Shape of M :", M.shape)
N = 996
Shape of M : (996, 996)
# Calculating average of M along the row
M_bar = np.mean(M, axis = 1, keepdims = True)
print("Shape of M_bar :", M_bar.shape)
Shape of M_bar : (996, 1)
# Subtracting M from M_bar
M_bar1 = M - M_bar
print("Shape of M_bar1 :", M_bar1.shape)
Shape of M_bar1 : (996, 996)
# Calculating average of M along the column
M_bar2 = np.mean(M_bar1, axis = 0, keepdims = True)
W = M_bar1 - M_bar2
print("Shape of W :", W.shape)
Shape of W : (996, 996)
# Eigen decomposition of W
U, S, V = LA.svd(W)
# Calculating diagonal matrix and square root of S
S1 = np.diag(S)
S2 = np.sqrt(S1)
# Calculating the dot product of U and S2
W1 = np.dot(U, S2)
print("Shape of W1 :", W1.shape)
W2 = W1[:,0:2]
# Plotting after eigen decomposition
plt.figure(figsize=[12,8])
x = W2[:,1]
y = W2[:,0]
plt.scatter(x, -y, color = 'maroon')
plt.show()
Shape of W1 : (996, 996)
<Figure size 864x576 with 0 Axes>
<matplotlib.collections.PathCollection at 0x1ef3f3b11c0>
The scatter plot plotted with the points is the IU logo.